#include "ssDBPoolThread.h"
#include "log/ssLogThread.h"

namespace StarSeeker
{


ssDBPoolThread::ssDBPoolThread()
	:m_mysqlPool(0)
{
}

ssDBPoolThread::ssDBPoolThread(ssMySQLPool* c)
	:m_mysqlPool(c)
{
}

ssDBPoolThread::~ssDBPoolThread()
{
}

void ssDBPoolThread::HandleMessage(ssMsg_s &m)
{
	//解析网络消息
	ssNetMsgHead* head = (ssNetMsgHead*)m.param[1];
	char* data = (char*)m.param[1];
	bool ret = OnDBMsg(head, data + sizeof(ssNetMsgHead), head->m_dwLen - sizeof(ssNetMsgHead), (u32)m.param[0]);

	if (ret)
	{
		//!!需要对象池
		delete[] data;
	} 
	else
	{
		PostMsg(m);
	}
}

void ssDBPoolThread::SetMySQLPool(ssMySQLPool* c)
{
	m_mysqlPool = c;
}

bool ssDBPoolThread::OnDBMsgNullRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	ssMySQLStmtQuery* query = m_mysqlPool->GetConnection();
	if (query)
	{
		if (0==query->QueryByID(id, dataLen, pData))
		{
			if (query->GetResultFlag(id) & DB_RESULT_INSERT_ID)
			{
				u32 row = (u32)query->m_affectedRows;
				u32 inId = (u32)query->m_insertID;
				ssDBResParam rp = {};
				//!!需要对象池
				ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
				rp.param = *param;
				rp.row = row;
				rp.insertId = inId;
				u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam);
				pHead->m_dwLen = sendLen;
				char* sendBuf = new char[sendLen + 8];
				memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
				memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
				SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
			}
		}
		else
		{
			SS_LOG->Print(query->m_error.c_str());
		}
		m_mysqlPool->ReleaseConnection(query);
		return true;
	}
	else
	{
		return false;
	}
}

bool ssDBPoolThread::OnDBMsgOneRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	ssMySQLStmtQuery* query = m_mysqlPool->GetConnection();
	if (query)
	{
		i32 ret = query->QueryByID(id, dataLen, pData);
		if (0 == ret)
		{
			ssReadBytes wb;
			ret = query->GetOneResult(id, wb);
			if (0 == ret)
			{
				u32 row = (u32)query->GetRows();
				ssDBResParam rp = {};

				ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
				rp.param = *param;
				rp.row = row;
				u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + (u32)wb.MaxSize();
				pHead->m_dwLen = sendLen;
				char* sendBuf = new char[sendLen + 8];

				memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
				memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
				if (row > 0 && !wb.IsEmpty())
				{
					memcpy(sendBuf + sizeof(ssNetMsgHead) + sizeof(ssDBResParam), wb.Buf(), wb.MaxSize());
				}
				SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
			}
		}
		else
		{
			SS_LOG->Error(query->m_error.c_str());
		}
		m_mysqlPool->ReleaseConnection(query);
		return true;
	} 
	else
	{
		return false;
	}
}

bool ssDBPoolThread::OnDBMsgMultiRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	ssMySQLStmtQuery* query = m_mysqlPool->GetConnection();
	if (query)
	{
		if (0 == query->QueryByID(id, dataLen, pData))
		{
			std::pair<int, ssLineBuffer&> ob = query->GetResultSet(id);
			if (0 == ob.first)
			{
				u32 row = (u32)query->GetRows();
				ssDBResParam rp = {};

				ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
				rp.param = *param;
				rp.row = row;
				u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + (u32)ob.second.Size();
				pHead->m_dwLen = sendLen;
				char* sendBuf = new char[sendLen + 8];
				char* sendFirst = sendBuf;

				memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
				sendBuf += sizeof(ssNetMsgHead);
				memcpy(sendBuf, &rp, sizeof(ssDBResParam));
				if (row > 0)
				{
					sendBuf += sizeof(ssDBResParam);
					memcpy(sendBuf, ob.second.Buf(), ob.second.Size());
				}
				SendResponse(connectID, (ssNetMsgHead*)sendFirst, sendFirst, sendLen);
			}
			else
			{
				SS_LOG->Error(query->m_error.c_str());
			}
		}
		else
		{
			SS_LOG->Print(query->m_error.c_str());
		}

		m_mysqlPool->ReleaseConnection(query);
		return true;
	}
	else
	{
		return false;
	}
}

void ssDBPoolThread::OnDBMsgCleanBuffer()
{
	m_mysqlPool->ClearAllBuffer();
}

}
